home *** CD-ROM | disk | FTP | other *** search
- {
- SEAN PALMER
-
- I've been playing around with it as a way to make 'heat-seeking
- missiles' in games. Very interesting...
-
- What I do is have the points set up as follows:
-
- 1 : current position
- 2&3 : current speed + the current position
- 4 : destination
-
- and update current position by indexing somewhere into the curve (like
- at $100 out of $FFFF
-
- This works very well. Problem is that I don't know of a good way to
- change the speed.
-
- Here is a simple demo that makes a dot chase the mouse cursor (needs
- VGA as written) that shows what I mean.
-
- If ANYBODY can make this work smoother or improve on it in any way I
- would appreciate being told how... 8)
- }
-
- uses
- mouse, crt; { you will need to change accesses to the mouse unit }
- { to use a mouse package that you provide }
- type
- coord = record
- x, y : word;
- end;
- CurveDataRec = array [0..65521 div sizeof(coord)] of coord;
-
- const
- nSteps = 1 shl 8; {about 8 for smoothness (dots), 4 for speed (lines)}
-
- var
- color : byte;
- src, spd,
- dst, mov1,
- mov2 : coord;
- i : integer;
-
- procedure plot(x, y : word);
- begin
- mem[$A000 : y * 320 + x] := color;
- end;
-
- function fracMul(f, f2 : word) : word;
- Inline(
- $58/ {pop ax}
- $5B/ {pop bx}
- $F7/$E3/ {mul bx}
- $89/$D0); {mov ax,dx}
-
- function mul(f, f2 : word) : longint;
- inline(
- $58/ {pop ax}
- $5B/ {pop bx}
- $F7/$E3); {mul bx}
-
-
- {this is the original full BSpline routine}
-
- procedure drawBSpline(var d0 : coord; nPoints : word);
- const
- nsa = $10000 div 6;
- nsb = $20000 div 3;
- step = $10000 div nSteps;
- var
- i, xx, yy : word;
- t1, t2, t3 : word;
- c1, c2, c3, c4 : word;
- d : curveDataRec absolute d0;
- begin
- t1 := 0;
- color := 32 + 2;
- for i := 0 to nPoints - 4 do
- begin
- {algorithm converted from Steve Enns' original Basic subroutine}
- repeat
- t2 := fracMul(t1, t1);
- t3 := fracMul(t2, t1);
- c1 := (integer(t2 - t1) div 2) + nsa - fracmul(nsa, t3);
- c2 := (t3 shr 1) + nsb - t2;
- c3 := ((t2 + t1 - t3) shr 1) + nsa;
- c4 := fracmul(nsa, t3);
- xx := (mul(c1, d[i].x) + mul(c2, d[i + 1].x) +
- mul(c3, d[i + 2].x) + mul(c4, d[i + 3].x)) shr 16;
- yy := (mul(c1, d[i].y) + mul(c2, d[i + 1].y) +
- mul(c3, d[i + 2].y) + mul(c4, d[i + 3].y)) shr 16;
- plot(xx, yy);
- inc(t1, step);
- until t1 = 0; {this is why nSteps must be even power of 2}
- inc(color);
- end;
- end;
-
-
- {find 1/nth point in BSpline} {this is what does the B-Spline work}
-
- procedure moveTowards(d1, d2, d3, d4 : coord; t1 : word; var mov : coord);
- const
- nsa = $10000 div 6;
- nsb = $20000 div 3;
- var
- t2, t3 : word;
- c1, c2,
- c3, c4 : word;
- begin
- t2 := fracMul(t1, t1);
- t3 := fracMul(t2, t1);
- c1 := (integer(t2 - t1) div 2) + nsa - fracmul(nsa, t3);
- c2 := (t3 shr 1) + nsb - t2;
- c3 := ((t2 + t1 - t3) shr 1) + nsa;
- c4 := fracmul(nsa, t3);
- mov.x := (mul(c1, d1.x) + mul(c2, d2.x) + mul(c3, d3.x) + mul(c4, d4.x)) shr 16;
- mov.y := (mul(c1, d1.y) + mul(c2, d2.y) + mul(c3, d3.y) + mul(c4, d4.y)) shr 16;
- end;
-
- begin
- asm
- mov ax, $13
- int $10
- end; {init vga/mcga graphics}
-
- {mouse.init;}
- mshow;
-
- src.x := 5;
- src.y := 5;
- spd.x := 5;
- spd.y := 5;
- dst.x := 315;
- dst.y := 190;
-
- repeat
- {for i:=0 to 23 do begin}
- { color:=i+32;}
- { inc(dst.x,i);}
- delay(10);
- {mouse.check;} {this loads Mouse.X, Mouse.Y, Mouse.Button from driver}
- mhide;
- color := 15;
- plot(src.x, src.y);
- color := 14;
- plot(spd.x, spd.y);
- dst.x := mousex shr 1;
- dst.y := mousey;
- color := 1;
- plot(dst.x, dst.y);
- mshow;
-
- {the parameters in these next two lines can be changed}
- {I have played with almost all possible combinations and}
- {most work, but not well, so don't be afraid to play around}
- {But I think an entirely different approach is needed for the}
- {second moveTowards..}
-
- moveTowards(src, src, spd, dst, $0010, mov1);
- moveTowards(src, spd, dst, dst, $5000, mov2);
- src := mov1;
- longint(spd) := (longint(spd) * 7 + longint(mov2)) shr 3 and $1FFF1FFF;
- until 1=0;
-
- mhide;
-
- asm
- mov ax, 3
- int $10
- end; {text mode again}
- end.
-